##################################################
#  Teamspeak v2.0                                #
#    Author: PezCore aka DieSucker               #
#  Tested on Eggdrop v1.6.17                     # 
##################################################
#                                                #
#                                                #
#                                                #
# This is a TCL Script designed to query a       #
# TeamSpeak server and post the nick and their   #
# time one the server into a channel.            #
# 3/30/2005 v2.0 - Added channels list           #
#                  Server info                   #
#                  cleaned up some outputs       #
# 3/20/2005 v1.2 - Added multi-server support    #
# 3/11/2005 v1.1 - Fixed The server time out     #
#                  it now gives an error if the  #
#                  server is offline or you      #
#                  give a BAD IP/PORT. It will   #
#                  take a minute for the it to   #
#                  time-out                      #
# 2/23/2005 v1.0 - rewrote most of the script    #
# 8/13/2004 v0.9 - Intial script by Vitto        #
# Many THANKS goes to MC_8                       #
# If you need me, #donuthole on irc.protium.org  #
# or email me diesucker@kc.rr.com                #
#                                                #
# Things-To-Do: Maybe add an HTML setting        #
#               Also add/delete servers          #
##################################################
array unset ts_server

# Configuration: 

# Set here a list of TeamSpeak servers, and there information. 
# Specify as many ts_server(<short_name>)'s as you need. 
# Syntax: 
#   set ts_server(<short_name>) [list "<full name>" "<ip>" "<port>" "<tcpquery>"] 

set ts_server(c4w) [list "Servername" "127.0.0.1" "8767" "51234"]

######################################################################################
###############Coding, Please don't edit below########################################
######################################################################################
unset -nocomplain Name 
unset -nocomplain Value
foreach {Name Value} [array get ts_server] { 
  array unset ts_server $Name 
  array set ts_server [list [string tolower $Name] $Value] 
} 
unset -nocomplain Name 
unset -nocomplain Value 

#Public Binding
bind pub - !ts TS:start
bind pub - !tsc TS:channels
bind pub - !tsi TS:serverinfo
bind pub - !tsservers TS:servers
bind pub - !tshelp TS:help

proc TS:servers {nick uhost handle channel text} { 
  set list [array names ::ts_server] 
  if {![llength $list]} { 
    putserv "PRIVMSG $channel :\0034,0There are no TeamSpeak servers currently defined, sorry." 
  } else { 
    putserv "PRIVMSG $channel :\0034,0List of availble TeamSpeak servers:\0033,0 [join $list ", "]" 
  } 
} 
#######Grabbing Server Info#############


proc TS:serverinfo {nick uhost handle channel text} {
   global ts
   set text [string tolower $text] 
   if {$text == ""} {
     putserv "PRIVMSG $channel :\0034,0Sorry, please specify a valid server selection. Use !tsservers to find supported servers"
     return 0
   } 
   if {[lsearch -exact [array names ::ts_server] $text] == "-1"} { 
     putserv "PRIVMSG $channel :\0034,0 Sorry, '$text' isn't a valid server selection. Please us !tsservers to find supported servers" 
     return 0 
   } 
   foreach {ts(servername) ts(ip) ts(port) ts(tcpquery)} $::ts_server($text) break
   set sock [connect $ts(ip) $ts(tcpquery)]
   close [open "scripts/tsserverinfo.txt" w]
   close [open "scripts/tsserverinfo2.txt" w]
   set ts(user:$sock) "" ; set ts(count:$sock) 0
   set ts(chan:$sock) "" ; set ts(arg:$sock) "$channel"
   set ts(arg) "$channel"
   set ts(players:$sock) 0
   set ts(last:$sock) ""
   control $sock TS:servercontrol
}
proc TS:servercontrol {sock input} {
   global ts
   if {$input == ""} {
     putserv "PRIVMSG $ts(arg) :\0034,0 The TeamSpeak Server has timed-out. Either The TeamSpeak server is offline or an Invalid IP
                                   was specified"
     return 1
   }
   if {$ts(last:$sock) == ""} {
     if {$input == {[TS]}} {
     putdcc $sock "sel $ts(port)"
     set ts(last:$sock) sel
     return 0
    }
   }
   if {$ts(last:$sock) == "sel"} {
     if {$input == "OK"} {
       putdcc $sock "si"
       set ts(last:$sock) si
       return 0
     }
    }
   if {$ts(last:$sock) == "si"} {
     if {$input == "OK"} {
       putdcc $sock "gi"
       set ts(last:$sock) gi
       return 0
     }
   set io2 [open "scripts/tsserverinfo.txt" a]
    puts $io2 "$input"; close $io2; return 0
   }
   if {$ts(last:$sock) == "gi"} {
     if {$input == "OK"} {
       TS:serverend
       return 1
     }
    set io3 [open "scripts/tsserverinfo2.txt" a]
    puts $io3 "$input"
    close $io3
    return 0
    }
 return 0
}

proc TS:serverend {} {
    global ts
    set info [open "scripts/tsserverinfo.txt" r]
    set info1 [read -nonewline $info]  
    close $info
    set vers [open "scripts/tsserverinfo2.txt" r]
    set vers1 [read -nonewline $vers]
    close $vers
    file delete -force -- "scripts/tsserverinfo.txt"
    set vers2 [split $vers1 "\n"]
    set vers3 [lindex $vers2 1]
    set vers4 [split $vers3 "="]
    set vers5 [lindex $vers4 1]
    set info2 [split $info1 "\n"]
    set name1 [lindex $info2 1]
    set name2 [split $name1 "="]
    set name3 [lindex $name2 1]
    set welcome1 [lindex $info2 3]
    set welcome2 [lindex [split $welcome1 "="] 1]
    set max1 [lindex $info2 9]
    set max2 [lindex [split $max1 "="] 1]
    set plat [lindex $info2 2]
    set plat2 [lindex [split $plat "="] 1]
    set users [lindex $info2 28]
    set users2 [lindex [split $users "="] 1]
    set channs [lindex $info2 29]
    set channs2 [lindex [split $channs "="] 1]
    set uptime [lindex $info2 27]
    set uptime2 [lindex [split $uptime "="] 1]
    set uptime3 [duration $uptime2]
    set uptime5 [split $uptime3 " "]
    set uptime4 [llength $uptime5]
    if {$uptime4 == "10"} {
      set test14 "[lindex $uptime5 0]w[lindex $uptime5 2]d[lindex $uptime5 4]h[lindex $uptime5 6]m"
    }
    if {$uptime4 == "8"} {
      set test14 "[lindex $uptime5 0]d[lindex $uptime5 2]h[lindex $uptime5 4]m"
    }
    if {$uptime4 == "6"} { 
      set test14 "[lindex $uptime5 0]h[lindex $uptime5 2]m" 
    } 
    if {$uptime4 == "4"} { 
      set test14 "0h[lindex $uptime5 0]m"
    } 
    if {$uptime4 == "2"} { 
      set test14 "[lindex $uptime5 0]s" 
    } 
    putserv "PRIVMSG $ts(arg) :\0034,0Server Info For\0033,0 $ts(servername)($ts(ip):$ts(port)) :\0031,0 \002Name:\002 $name3 \002Welcome Message:\002 $welcome2 \002Max Users:\002 $max2 \002Platform:\002 $plat2 \002Current users:\002 $users2 \002 Total Channels:\002 $channs2 \002Uptime:\002 $test14 \002Version:\002 $vers5"
} 

#################End Of Server Info################################


#################Server channels###################################


proc TS:channels {nick uhost handle channel text} {
    global ts
    if {$text == ""} {
      putserv "PRIVMSG $channel :\0034,0Sorry, please specify a valid server selection. Use !tsservers to find supported servers"
      return 0
    } 
    set text [string tolower $text] 
    if {[lsearch -exact [array names ::ts_server] $text] == "-1"} { 
      putserv "PRIVMSG $channel :\0034,0Sorry, '$text' isn't a valid server selection. Use !tsservers to find supported servers"
      return 0 
    } 
    foreach {ts(servername) ts(ip) ts(port) ts(tcpquery)} $::ts_server($text) break
    set sock [connect $ts(ip) $ts(tcpquery)]
    close [open "scripts/tschannels.txt" w]
    set ts(user:$sock) "" ; set ts(count:$sock) 0
    set ts(chan:$sock) "" ; set ts(arg:$sock) "$channel"
    set ts(arg) "$channel"
    set ts(players:$sock) 0
    set ts(last:$sock) ""
    control $sock TS:chancontrol
}

proc TS:chancontrol {sock input} {
    global ts
    if {$input == ""} {
      putserv "PRIVMSG $ts(arg) :\0034,0 The TeamSpeak Server has timed-out. Either The TeamSpeak server is offline or an Invalid IP
                                   was specified" 
      return 1
      }
    if {$ts(last:$sock) == ""} { 
      if {$input == {[TS]}} { 
      putdcc $sock "sel $ts(port)"
      set ts(last:$sock) sel 
      return 0 
      }
    } 
    if {$ts(last:$sock) == "sel"} { 
      if {$input == "OK"} {
        putdcc $sock "cl"
        set ts(last:$sock) cl
        return 0
       }
   }
   if {$ts(last:$sock) == "cl"} {
     if {$input == "OK"} {
       TS:chanend
       return 1
       }
   set io [open "scripts/tschannels.txt" a]
   puts $io "/ $input"
   close $io
   return 0
  }
 return 0 
}

proc TS:chanend {} {
   global ts
   set ts(channels1) [open "scripts/tschannels.txt" r]
   set ts(channels2) [read $ts(channels1)]
   set ts(channels3) [split $ts(channels2) "\n"]
   close $ts(channels1)
   file delete -force -- "scripts/tschannels.txt"
   set ts(channels3) [lreplace $ts(channels3) 0 0]
   set ts(channels4) [llength $ts(channels3)]
   set ts(channels4) [expr "$ts(channels4) - 1"]
   set ts(ch1) [lindex $ts(channels3) 0]
   set ts(ch2) [lindex [split $ts(ch1) \t] 5]
   set ts(ch3) [lindex [split $ts(ch2) {"}] 1]
   set ts(channelsoutput) ": $ts(ch3)"
   set j 1 
   while {$j < $ts(channels4)} {
        set ts(channels6) [lindex $ts(channels3) $j]
        set ts(channels7) [lindex [split $ts(channels6) \t] 5]
        set ts(channels8) [split $ts(channels7) {"}]
        set ts(channels9) [lindex $ts(channels8) 1]
        append ts(channelsoutput) ", " $ts(channels9)
        incr j
        }
   putserv "PRIVMSG $ts(arg) :\0034,0 Channels on\0033,0 $ts(servername)($ts(ip):$ts(port)):\0036,0($ts(channels4))\0031,0$ts(channelsoutput)"
}

#############End of channels#####################

#############Users Connected#####################


proc TS:start {nick uhost handle channel text} { 
    global ts
    set text [string tolower $text]
    if {$text == ""} {
      putserv "PRIVMSG $channel :\0034,0Sorry, please specify a valid server selection. Use !tsservers to find supported servers"
      return 0
     } 
    if {[lsearch -exact [array names ::ts_server] $text] == "-1"} { 
      putserv "PRIVMSG $channel :\0034,0Sorry, '$text' isn't a valid server selection. Use !tsservers to find supported servers" 
      return 0 
     } 
    foreach {ts(servername) ts(ip) ts(port) ts(tcpquery)} $::ts_server($text) break 
    set sock [connect $ts(ip) $ts(tcpquery)] 
    close [open "scripts/tstester.txt" w] 
    set ts(user:$sock) "" ; set ts(count:$sock) 0 
    set ts(chan:$sock) "" ; set ts(arg:$sock) "$channel" 
    set ts(arg) "$channel" 
    set ts(players:$sock) 0
    set ts(last:$sock) ""
    control $sock TS:control
}

proc TS:control {sock input} { 
    global ts
    if {$input == ""} {
      putserv "PRIVMSG $ts(arg) :\0034,0 The TeamSpeak Server has timed-out. Either The TeamSpeak server is offline or an Invalid IP was specified"
      return 1
    } 
    if {$ts(last:$sock) == ""} { 
      if {$input == {[TS]}} { 
        putdcc $sock "sel $ts(port)" 
        set ts(last:$sock) sel 
        return 0 
      }
    } 
    if {$ts(last:$sock) == "sel"} { 
      if {$input == "OK"} { 
        putdcc $sock "pl" 
        set ts(last:$sock) pl 
        return 0 
      }
    }
    if {$ts(last:$sock) == "pl"} { 
      if {$input == "OK"} {  
        TS:end
        return 1 
      } 
    set io [open "scripts/tstester.txt" a] 
    puts $io "/ $input"; close $io; return 0 
    }
  return 0 
}

proc TS:end {} {
    global ts
    set ts(players2) "scripts/tstester.txt"
    set ts(players3) [open $ts(players2) r]
    set ts(playerdata) [read $ts(players3)]
    set ts(plines) [split $ts(playerdata) "\n"]
    close $ts(players3)
    file delete -force -- "scripts/tstester.txt"
    set ltd 0 
    set ts(plines) [lreplace $ts(plines) $ltd $ltd]
    set i [open $ts(players2) w]
    puts $i [join $ts(plines) ""]
    close $i
    set ts(nlines) [llength $ts(plines)]
    set ts(lines2) [expr "$ts(nlines) - 1"]
    set channeloutput [list ":"]
    set i 0 
    while {$i < $ts(lines2)} {
         set users2 [lindex $ts(plines) $i]
         set users1 [regexp {\d\t(\d+?)\t[\d|\t]+?\t".+?"\t"(.+?)"\t"(.*?)"\t} [lindex $ts(plines) $i] {\1\2\3} input nik Name] 
         set test11 [duration [lindex [split $users2 \t] 8]]
         set test12 [split $test11 " "]
         set test13 [llength $test12]
         if {$test13 == "10"} {
           set test14 "([lindex $test12 0]w[lindex $test12 2]d[lindex $test12 4]h[lindex $test12 6]m)"
         }
         if {$test13 == "8"} {
           set test14 "([lindex $test12 0]d[lindex $test12 2]h[lindex $test12 4]m)"
         }
         if {$test13 == "6"} { 
           set test14 "([lindex $test12 0]h[lindex $test12 2]m)" 
         } 
         if {$test13 == "4"} { 
           set test14 "(0h[lindex $test12 0]m)" 
         } 
         if {$test13 == "2"} { 
           set test14 "([lindex $test12 0]s)" 
         } 
         lappend channeloutput  $nik $test14
         incr i 
    }
   if {$ts(lines2) == 0} { 
     putserv "PRIVMSG $ts(arg) :\0034,0There Are NO Users Connected to\0033,0 $ts(servername)($ts(ip):$ts(port))"
     } else {
           putserv "PRIVMSG $ts(arg) :\0034,0Current Users Connected to \0033,0$ts(servername)($ts(ip):$ts(port)): \0036,0($ts(lines2))\0031,0 $channeloutput" 
     }
}

###########End of Users Connected##############

###########TS Script Help######################

proc TS:help {nick uhost handle channel text} {
     putserv "NOTICE $nick : TeamSpeak TCL v2.0 Written by DieSucker, cleaned up by MC_8, original code by Vitto"
     putserv "NOTICE $nick : Commands :"
     putserv "NOTICE $nick : !ts (servername) - returns current users connected"
     putserv "NOTICE $nick : !tsi (servername) - returns information for the given server"
     putserv "NOTICE $nick : !tsc (servername) - returns channels from the server"
     putserv "NOTICE $nick : !tsservers - returns list of supported servers" 
     putserv "NOTICE $nick : Any bugs or comments send to diesucker@kc.rr.com"
}

##########TS Script Help END######################
putlog " TeamSpeak Info v2.0 By DieSucker/MC_8/Vitto loaded "
